package com.webserver;



import java.security.cert.*;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.*;
import java.math.*;
import java.util.Date;
import java.util.Hashtable;
import java.util.Vector;

import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.provider.*;
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.misc.NetscapeCertType;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.x509.*;

/**
 * A simple example that generates an attribute certificate.
 */
public class AttrCertExample {
    static X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator();
    static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();

    /**
     * we generate the AC issuer's certificate
     */
    
   
    public static X509Certificate createAcIssuerCert(PublicKey pubKey,
            PrivateKey privKey) throws Exception {
        //
        // signers name 
        //
        String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate";

        //
        // subjects name - the same as we are self signed.
        //
        String subject = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate";

        //
        // create the certificate - version 1
        //

        v1CertGen.setSerialNumber(BigInteger.valueOf(10));
        v1CertGen.setIssuerDN(new X509Principal(issuer));
        v1CertGen.setNotBefore(new Date(System.currentTimeMillis()
                - 1000L * 60 * 60 * 24 * 30));
        v1CertGen.setNotAfter(new Date(System.currentTimeMillis()
                + (1000L * 60 * 60 * 24 * 30)));
        v1CertGen.setSubjectDN(new X509Principal(subject));
        v1CertGen.setPublicKey(pubKey);
        v1CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption");

        X509Certificate cert = v1CertGen
                .generateX509Certificate(privKey);

        cert.checkValidity(new Date());

        cert.verify(pubKey);

        return cert;
    }

    /**
     * we generate a certificate signed by our CA's intermediate certficate
     */
    
    public static X509Certificate createClientCert(PublicKey pubKey,
            PrivateKey caPrivKey, PublicKey caPubKey) throws Exception {
        //
        // issuer
        //
        String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate";

        //
        // subjects name table.
        //
        Hashtable attrs = new Hashtable();
        Vector order = new Vector();

        attrs.put(X509Principal.C, "AU");
        attrs.put(X509Principal.O, "The Legion of the Bouncy Castle");
        attrs.put(X509Principal.L, "Melbourne");
        attrs.put(X509Principal.CN, "Eric H. Echidna");
        attrs.put(X509Principal.EmailAddress,
                "feedback-crypto@bouncycastle.org");

        order.addElement(X509Principal.C);
        order.addElement(X509Principal.O);
        order.addElement(X509Principal.L);
        order.addElement(X509Principal.CN);
        order.addElement(X509Principal.EmailAddress);

        //
        // create the certificate - version 3
        //
        v3CertGen.reset();

        v3CertGen.setSerialNumber(BigInteger.valueOf(20));
        v3CertGen.setIssuerDN(new X509Principal(issuer));
        v3CertGen.setNotBefore(new Date(System.currentTimeMillis()
                - 1000L * 60 * 60 * 24 * 30));
        v3CertGen.setNotAfter(new Date(System.currentTimeMillis()
                + (1000L * 60 * 60 * 24 * 30)));
        v3CertGen.setSubjectDN(new X509Principal(order, attrs));
        v3CertGen.setPublicKey(pubKey);
        v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption");

        //
        // add the extensions
        //

        v3CertGen.addExtension(MiscObjectIdentifiers.netscapeCertType,
                false, new NetscapeCertType(
                        NetscapeCertType.objectSigning
                                | NetscapeCertType.smime));

        X509Certificate cert = v3CertGen
                .generateX509Certificate(caPrivKey);
        
        cert.checkValidity(new Date());

        cert.verify(caPubKey);

        return cert;
    }
    
    public static X509Certificate createClientCert(UserInformation userInfo, PrivateKey caPrivKey, PublicKey caPubKey) throws Exception {
        //
        // issuer
        //
        String issuer = "C=AU, O=The Legion of the Bouncy Castle, OU=Bouncy Primary Certificate";
        PublicKey pubKey = userInfo.getPublicKey();
        //
        // subjects name table.
        //
        Hashtable attrs = new Hashtable();
        Vector order = new Vector();

        attrs.put(X509Principal.C, userInfo.getCountry());
        attrs.put(X509Principal.O, userInfo.getOrganization());
        attrs.put(X509Principal.L, userInfo.getLocation());
        attrs.put(X509Principal.CN, userInfo.getCn());
        attrs.put(X509Principal.EmailAddress,
                userInfo.getEmail());

        order.addElement(X509Principal.C);
        order.addElement(X509Principal.O);
        order.addElement(X509Principal.L);
        order.addElement(X509Principal.CN);
        order.addElement(X509Principal.EmailAddress);

        //
        // create the certificate - version 3
        //
        v3CertGen.reset();

        v3CertGen.setSerialNumber(BigInteger.valueOf(20));
        v3CertGen.setIssuerDN(new X509Principal(issuer));
        v3CertGen.setNotBefore(new Date(System.currentTimeMillis()
                - 1000L * 60 * 60 * 24 * 30));
        v3CertGen.setNotAfter(new Date(System.currentTimeMillis()
                + (1000L * 60 * 60 * 24 * 30)));
        v3CertGen.setSubjectDN(new X509Principal(order, attrs));
        v3CertGen.setPublicKey(pubKey);
        v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption");

        //
        // add the extensions
        //

        v3CertGen.addExtension(MiscObjectIdentifiers.netscapeCertType,
                false, new NetscapeCertType(
                        NetscapeCertType.objectSigning
                                | NetscapeCertType.smime));

        X509Certificate cert = v3CertGen
                .generateX509Certificate(caPrivKey);

        cert.checkValidity(new Date());

        cert.verify(caPubKey);
        
        return cert;

    }
}
